from d115.utils.listutils import compose
from random import randint
from decimal import Decimal

class Infix:
    def __init__(self, f):
        self.function = f
    def __ror__(self, other):
        return Infix(lambda x, self=self, other=other: self.function(other, x))
    def __or__(self, other):
        return self.function(other)
    def __rlshift__(self, other):
        return Infix(lambda x, self=self, other=other: self.function(other, x))
    def __rshift__(self, other):
        return self.function(other)
    def __call__(self, v1, v2):
        return self.function(v1, v2)

# convert anything to a Decimal
dcml = compose(Decimal, str) 

def is_int(s):
    try: int(s) 
    except: return False
    return True

@Infix
def pct(p, x): 
    """ Calculate p percent from x """
    return dcml(p)*dcml(x)/dcml(100)

mark_up = lambda p,v: dcml(v) + dcml(p)*dcml(v)/dcml(100)
mark_down = lambda p,v: mark_up(dcml(-1)*dcml(p), v)


def closed_interval_overlap(f1, f2, s1, s2):
    """
    return True if the intervals [f1,f2] and [s1,s2] overlap
    """
    return any([(s1 <= f1 <= s2),
                (s1 <= f2 <= s2),
                (f1 <= s1 <= f2),
                (f1 <= s2 <= f2),
                ])

def int2roman(n):
    Rom={}
    Rom["M"] = 1000
    Rom["CM"] = 900
    Rom["D"] = 500
    Rom["CD"] = 400
    Rom["C"] = 100
    Rom["XC"] = 90
    Rom["L"] = 50
    Rom["XL"] = 40
    Rom["X"] = 10
    Rom["IX"] = 9
    Rom["V"] = 5
    Rom["IV"] = 4
    Rom["I"] = 1
    RomSeq = ( "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" )
    result=""
    if n < 1 or n > 4000:
        return None
        ## raise IndexError?
    for i in RomSeq:
        while Rom[i] <= n:
            result = result + i
            n = n - Rom[i]
    return result

def float_or_zero(value):
    try:
        return "%.2f" % float(str(value).replace(',', '.'))
    except:
        return 0
